package com.game.doudizhu.service;

import com.game.doudizhu.model.*;
import com.game.doudizhu.repository.CardRepository;
import com.game.doudizhu.repository.GameRoomRepository;
import com.game.doudizhu.common.constants.GameConstants;
import com.game.doudizhu.common.exception.GameException;
import com.game.doudizhu.task.RoomCleanupTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class GameRoomService {
    private static final Logger log = LoggerFactory.getLogger(GameRoomService.class);

    @Autowired
    private GameRoomRepository gameRoomRepository;

    @Autowired
    private CardRepository cardRepository;

    @Autowired
    private PlayerService playerService;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    // === 业务方法 ===

    public GameRoom canJoinRoom(Long roomId, Player player) {
        GameRoom room = getRoomOrThrow(roomId);
        validateNewJoin(room);
        return room;
    }

    @Transactional
    public GameRoom createRoom(Player player) {
        try {
            GameRoom room = new GameRoom();
            room.setRoomName("房间 " + System.currentTimeMillis() % 1000000);
            room.setStatus(GameConstants.Status.WAITING);

            player.setReady(false);
//            room.getPlayers().add(player);
//            room.setPlayerCount(1);

            return gameRoomRepository.save(room);
        } catch (Exception e) {
            throw new GameException("创建房间失败: " + e.getMessage());
        }
    }

    @Transactional
    public GameRoom handlePlayerLeave(Long roomId, Long playerId) {
        GameRoom room = getRoomOrThrow(roomId);
        Player player = playerService.getPlayer(playerId);

        // 先清除玩家准备状态
        room.playerUnready(playerId);
        
        // 使用 removePlayer 方法移除玩家
        room.removePlayer(player);
        
        // 保存并刷新房间
        room = gameRoomRepository.saveAndFlush(room);

        // 如果房间空了，或者只剩下AI玩家，删除房间和AI玩家
        if (room.getPlayerCount() == 0 || isOnlyAIPlayers(room)) {
            deleteAIPlayers(room);
            gameRoomRepository.delete(room);
            return null;
        }

        // 如果是地主离开，结束游戏
        if (playerId.equals(room.getLandlordId())) {
            room.setStatus(GameConstants.Status.FINISHED);
            room = gameRoomRepository.save(room);
        }

        return room;
    }

    @Transactional
    public GameRoom handlePlayerDisconnect(Long roomId, Long playerId) {
        GameRoom room = getRoomOrThrow(roomId);
        // 只记录断开连接状态，不移除玩家
        room.handlePlayerDisconnect(playerId.toString());
        return gameRoomRepository.save(room);
    }

    @Transactional
    public GameRoom handlePlayerReconnect(GameRoom room, Player player) {
        room.handlePlayerReconnect(player.getId().toString());
        return gameRoomRepository.save(room);
    }

    @Transactional
    public GameRoom addNewPlayer(GameRoom room, Player player) {
        validateNewJoin(room);
        
        // 从数据库获取完整的玩家信息
        Player fullPlayer = playerService.getPlayer(player.getId());
        fullPlayer.setReady(false);
        
        // 使用 addPlayer 方法添加玩家到房间
        room.addPlayer(fullPlayer);
        
        // 保存并刷新房间
        return gameRoomRepository.saveAndFlush(room);
    }

    @Transactional
    public GameRoom updateRoomStatus(Long roomId, String status) {
        GameRoom room = getRoomOrThrow(roomId);
        room.setStatus(status);
        return gameRoomRepository.save(room);
    }

    @Transactional
    public GameRoom setLandlord(Long roomId, Long landlordId) {
        GameRoom room = getRoomOrThrow(roomId);
        room.setLandlordId(landlordId);
        return gameRoomRepository.save(room);
    }

    @Transactional
    public GameRoom createAIRoom(Player player) {
        try {
            GameRoom room = new GameRoom();
            room.setRoomName("AI房间 " + System.currentTimeMillis() % 1000000);
            room.setStatus(GameConstants.Status.WAITING);
            
            // 生成唯一的AI玩家名称
            long timestamp = System.currentTimeMillis();
            AIPlayer ai1 = AIPlayer.createAIPlayer("AI玩家" + timestamp);
            AIPlayer ai2 = AIPlayer.createAIPlayer("AI玩家" + (timestamp + 1));
            
            ai1.setReady(true);
            ai2.setReady(true);
            
            // 保存AI玩家
            ai1 = playerService.savePlayer(ai1);
            ai2 = playerService.savePlayer(ai2);
            
            // 先保存房间
            room = gameRoomRepository.save(room);
            
            // 使用 addPlayer 方法添加AI玩家
            room.addPlayer(ai1);
            room.addPlayer(ai2);
            
            // 设置准备状态
            room.playerReady(ai1.getId());
            room.playerReady(ai2.getId());
            
            // 最终保存并刷新房间
            return gameRoomRepository.saveAndFlush(room);
            
        } catch (Exception e) {
            throw new GameException("创建AI房间失败: " + e.getMessage());
        }
    }

    // === 查询方法 ===

    @Transactional(readOnly = true)
    public List<GameRoom> getAvailableRooms() {
        return gameRoomRepository.findByStatusAndPlayerCountLessThan(
                GameConstants.Status.WAITING,
                GameConstants.Room.MAX_PLAYERS
        );
    }

    @Transactional(readOnly = true)
    public List<GameRoom> getAllRooms() {
        return gameRoomRepository.findAll();
    }

    @Transactional(readOnly = true)
    public GameRoom getRoom(Long roomId) {
        return getRoomOrThrow(roomId);
    }

    // === 状态检查方法 ===
    public boolean isPlayerReconnecting(GameRoom room, Player player) {
        return room.getPlayers().stream()
                .anyMatch(p -> p.getId().equals(player.getId()));
    }

    public boolean canStartGame(GameRoom room) {
        return room.getPlayers().size() == GameConstants.Room.MAX_PLAYERS &&
               room.areAllPlayersReady();
    }

    public boolean shouldRemovePlayer(GameRoom room, String playerId) {
        return room.shouldRemovePlayer(playerId);
    }

    // === 玩家状态管理方法 ===
    @Transactional
    public void togglePlayerReady(GameRoom room, Player player) {
        if (room.isPlayerReady(player.getId())) {
            room.playerUnready(player.getId());
        } else {
            room.playerReady(player.getId());
        }
        room.getPlayers().forEach(p -> p.setReady(room.isPlayerReady(p.getId())));
        gameRoomRepository.save(room);
    }

    @Transactional
    public void resetRoomReadyStatus(Long roomId) {
        GameRoom room = getRoomOrThrow(roomId);
        room.resetReadyStatus();
        gameRoomRepository.save(room);
    }

    // === 辅助方法 ===
    public GameRoom getRoomOrThrow(Long roomId) {
        return gameRoomRepository.findById(roomId)
                .orElseThrow(() -> new GameException("房间不存在"));
    }

    private void validateNewJoin(GameRoom room) {
        if (room.getPlayerCount() >= GameConstants.Room.MAX_PLAYERS) {
            throw new GameException("房间已满");
        }
    }

    // === 房间维护方法 ===
    @Transactional
    public int cleanupInactiveRooms() {
        List<GameRoom> inactiveRooms = gameRoomRepository.findAll().stream()
                .filter(this::isRoomInactive)
                .collect(Collectors.toList());
        int count = inactiveRooms.size();

        for (GameRoom room : inactiveRooms) {
            try {
                handleInactiveRoom(room);
            } catch (Exception e) {
                // 记录错误但继续处理其他房间
                count--;
                log.error("清理房间 {} 失败: {}", room.getId(), e.getMessage());
            }
        }
        return count;
    }

    private boolean isRoomInactive(GameRoom room) {
        long currentTime = System.currentTimeMillis();
        long inactiveThreshold = GameConstants.Room.INACTIVE_THRESHOLD;

        // 检查房间是否长时间无活动
        if (currentTime - room.getLastActiveTime() > inactiveThreshold) {
            return true;
        }

        // 检查是否是空房间
        if (room.getPlayerCount() == 0) {
            return true;
        }

        // 检查是否只剩下AI玩家
        if (isOnlyAIPlayers(room)) {
            return true;
        }

        // 检查是否是已结束的游戏
        if (GameConstants.Status.FINISHED.equals(room.getStatus())) {
            return true;
        }

        // 检查是否所有玩家都断线
        if (room.getPlayerCount() > 0 && room.getPlayers().stream()
                .allMatch(player -> room.isPlayerDisconnected(player.getId().toString()))) {
            return true;
        }

        return false;
    }

    private void handleInactiveRoom(GameRoom room) {
        try {
            // 先删除AI玩家
            deleteAIPlayers(room);
            
            // 清理玩家关联
            room.getPlayers().clear();
            room = gameRoomRepository.saveAndFlush(room);
            
            // 清理其他资源
            cardRepository.removeCardsByRoomId(room.getId());
            
            // 删除房间
            gameRoomRepository.delete(room);
            
            log.info("已清理不活跃房间: {}", room.getId());
        } catch (Exception e) {
            log.error("清理房间 {} 失败: {}", room.getId(), e.getMessage());
            throw e;
        }
    }

    // 更新房间活动时间
    @Transactional
    public void updateRoomActivity(Long roomId) {
        GameRoom room = getRoomOrThrow(roomId);
        room.setLastActiveTime(System.currentTimeMillis());
        gameRoomRepository.save(room);
    }

    /**
     * 根据玩家ID查找其所在的房间
     */
    public GameRoom findRoomByPlayerId(Long playerId) {
        return gameRoomRepository.findByPlayerId(playerId)
                .orElse(null);
    }

    /**
     * 关闭房间
     */
    public void closeRoom(GameRoom room) {
        // 通知房间内的所有玩家
        room.getPlayers().forEach(player -> {
            try {
                messagingTemplate.convertAndSend(
                        "/topic/game/" + room.getId() + "/player/" + player.getId(),
                        new GameMessage("ROOM_CLOSED", "房间已被管理员关闭")
                );
            } catch (Exception e) {
                // 忽略消息发送失败
            }
        });

        // 更新房间状态
        room.setStatus("CLOSED");
        gameRoomRepository.save(room);

        // 清理房间资源
        cleanupRoom(room);
    }

    /**
     * 清理房间资源
     */
    private void cleanupRoom(GameRoom room) {
        // 删除AI玩家
        deleteAIPlayers(room);
        
        // 移除所有玩家
        room.getPlayers().clear();
        gameRoomRepository.save(room);
    }

    /**
     * 删除房间中的AI玩家
     */
    private void deleteAIPlayers(GameRoom room) {
        if (room.getPlayers() != null) {
            List<Player> aiPlayers = room.getPlayers().stream()
                    .filter(Player::isAI)
                    .collect(Collectors.toList());
            
            for (Player aiPlayer : aiPlayers) {
                try {
                    playerService.deletePlayer(aiPlayer.getId());
                } catch (Exception e) {
                    log.error("删除AI玩家失败: {}", e.getMessage());
                }
            }
        }
    }

    private void notifyPlayerLeft(GameRoom room, Player player) {
        try {
            messagingTemplate.convertAndSend(
                    "/topic/game/" + room.getId(),
                    new GameMessage("PLAYER_LEFT", player.getUsername() + " 离开了房间")
            );
        } catch (Exception e) {
            // 忽略消息发送失败
        }
    }

    // 检查房间是否只剩下AI玩家
    private boolean isOnlyAIPlayers(GameRoom room) {
        if (room.getPlayers() == null || room.getPlayers().isEmpty()) {
            return false;
        }
        return room.getPlayers().stream().allMatch(Player::isAI);
    }

}